]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
workspaceThumbnail: Track later hiding drop placeholder
authorMarco Trevisan (Treviño) <mail@3v1n0.net>
Fri, 31 Oct 2025 03:48:21 +0000 (04:48 +0100)
committerMarge Bot <marge-bot@gnome.org>
Mon, 3 Nov 2025 12:14:29 +0000 (12:14 +0000)
When closing the shell during a relayout we are getting this error:

    (gnome-shell:2559407): Gjs-CRITICAL **: 06:57:21.765: Object St.Bin,
    has been already disposed — impossible to access it.
    This might be caused by the object having been destroyed from C code
    using something such as destroy(), dispose(), or remove() vfuncs.
    == Stack trace for context 0x60991609b710 ==
    #0 b   resource:///org/gnome/shell/ui/workspaceThumbnail.js:1334 (5e050636fb0 @ 17)
    #1 i   resource:///org/gnome/shell/ui/main.js:279 (30c932d102e0 @ 119)

This is because the later we added is running even when not needed (e.g
when the placeholder is not visible already), but also because we may
run the later callback after the parent has been destroyed.

Prevent this to happen, by tracking the later

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3943>

js/ui/workspaceThumbnail.js

index 08d3d9b5c98a2b897f14d8eb8fccf6822e38576c..6bd834407d3c6d997754e5aa528a114332e6cd25 100644 (file)
@@ -688,6 +688,7 @@ export const ThumbnailsBox = GObject.registerClass({
     _onDestroy() {
         this._destroyThumbnails();
         this._unqueueUpdateStates();
+        this._clearDropPlaceholderLater();
 
         if (this._settings)
             this._settings.run_dispose();
@@ -769,6 +770,14 @@ export const ThumbnailsBox = GObject.registerClass({
         this.queue_relayout();
     }
 
+    _clearDropPlaceholderLater() {
+        if (!this._dropPlaceholderLater)
+            return;
+
+        global.compositor.get_laters().remove(this._dropPlaceholderLater);
+        delete this._dropPlaceholderLater;
+    }
+
     _getPlaceholderTarget(index, spacing, rtl) {
         const workspace = this._thumbnails[index];
 
@@ -1329,10 +1338,15 @@ export const ThumbnailsBox = GObject.registerClass({
             this._dropPlaceholder.allocate_preferred_size(
                 ...this._dropPlaceholder.get_position());
 
-            const laters = global.compositor.get_laters();
-            laters.add(Meta.LaterType.BEFORE_REDRAW, () => {
-                this._dropPlaceholder.hide();
-            });
+            this._clearDropPlaceholderLater();
+            if (this._dropPlaceholder.visible) {
+                const laters = global.compositor.get_laters();
+                this._dropPlaceholderLater = laters.add(
+                    Meta.LaterType.BEFORE_REDRAW, () => {
+                        this._dropPlaceholder.hide();
+                        delete this._dropPlaceholderLater;
+                    });
+            }
         }
 
         const childBox = new Clutter.ActorBox();
@@ -1360,10 +1374,15 @@ export const ThumbnailsBox = GObject.registerClass({
 
                 this._dropPlaceholder.allocate(childBox);
 
-                const laters = global.compositor.get_laters();
-                laters.add(Meta.LaterType.BEFORE_REDRAW, () => {
-                    this._dropPlaceholder.show();
-                });
+                this._clearDropPlaceholderLater();
+                if (!this._dropPlaceholder.visible) {
+                    const laters = global.compositor.get_laters();
+                    this._dropPlaceholderLater = laters.add(
+                        Meta.LaterType.BEFORE_REDRAW, () => {
+                            this._dropPlaceholder.show();
+                            delete this._dropPlaceholderLater;
+                        });
+                }
                 x += placeholderWidth + spacing;
             }